/*
frigOS
Licensed under GPLv3

This file contains definitions for using the buttons found on
the Robotis CM5 boards used with the Bioloid robot kits

TODO: only the up button is currently supported
*/

#ifndef DISABLE_BUTTONS
#ifndef __BUTTON_H__
#define __BUTTON_H__

#include <avr/io.h>

typedef enum
{
    UP_BUTTON = (1 << 0),
    DOWN_BUTTON = (1 << 1),
    LEFT_BUTTON = (1 << 2),
    RIGHT_BUTTON = (1 << 3),
    START_BUTTON = (1 << 4)
} Buttons;

typedef enum
{
    DDR_UP_BUTTON = (1 << DDE4),
    DDR_DOWN_BUTTON = (1 << DDE5),
    DDR_LEFT_BUTTON = (1 << DDE6),
    DDR_RIGHT_BUTTON = (1 << DDE7), // TODO
    DDR_START_BUTTON = (1 << DDD0)  // TODO
} Button_DDRs;

typedef enum
{
    PIN_UP_BUTTON = (1 << PINE4),
    PIN_DOWN_BUTTON = (1 << PINE5),
    PIN_LEFT_BUTTON = (1 << PINE6),
    PIN_RIGHT_BUTTON = (1 << PINE7), // TOD0
    PIN_START_BUTTON = (1 << PIND0)  // TODO
} Button_PIN;

typedef enum
{
    BUTTON_CLEAR = 0,
    BUTTON_PRESSED = 1
} ButtonState;

// TODO: determine what the limit should actually be
#define DEBOUNCE_LIMIT  1

// keep these as static inline functions so they can be used as monitor functions
// no debouncing; these just return the raw pin values
static inline uint8_t upButtonPressed(void)
{
    return (PORTE & PIN_UP_BUTTON);
}
static inline uint8_t downButtonPressed(void)
{
    return (PORTE & PIN_DOWN_BUTTON);
}
static inline uint8_t leftButtonPressed(void)
{
    return (PORTE & PIN_LEFT_BUTTON);
}
static inline uint8_t rightButtonPressed(void)
{
    return (PORTE & PIN_RIGHT_BUTTON);
}
static inline uint8_t startButtonPressed(void)
{
    return (PORTD & PIN_START_BUTTON);
}

// return a bit-field indicating what buttons are currently down
static inline uint8_t pollButtons(void)
{
    uint8_t ret = 0x00;

    if(upButtonPressed())
        ret |= UP_BUTTON;

    if(downButtonPressed())
        ret |= DOWN_BUTTON;

    if(leftButtonPressed())
        ret |= LEFT_BUTTON;

    if(rightButtonPressed())
        ret |= RIGHT_BUTTON;

    if(startButtonPressed())
        ret |= START_BUTTON;

    return ret;
}


void initButtons(void);

// monitors buttons and handles debouncing
// fires ??_BUTTON_PRESSED_EVENT events
uint8_t monitorButtons(void);

#endif // __BUTTON_H__
#endif //DISABLE_BUTTONS
